﻿using CoreEx.Common.Validation;
using LinFu.IoC.Configuration;
using LinFu.IoC.Interfaces;
using LinFu.IoC;

namespace CoreEx.Common.Implementation.Validation
{
    /// <summary>
    /// Validates the target instance by evaluating all <see cref="IValidationRule{T}"/> instances
    /// </summary>
    /// <typeparam name="T">The target type to validate.</typeparam>
    [Implements(typeof(IValidator<>))]
    public class Validator<T> : IValidator<T>,  IInitialize
    {
        /// <summary>
        /// Gets the <see cref="IRulesValidator"/> instance that is used to validate the target instance.
        /// </summary>
        protected IRulesValidator RulesValidator { get; private set; }

        /// <summary>
        /// Gets a <see cref="IValidationRules{T}"/> instance the contains all <see cref="IValidationRule{T}"/> for the target type.
        /// </summary>
        protected IValidationRules<T> ValidationRules { get; private set; }

        /// <summary>
        /// Validates the <paramref name="target"/> instance.
        /// </summary>
        /// <param name="target">The target instance to validate.</param>
        /// <returns>A <see cref="string"/> that contains a textual representation of the broken rule, if any.</returns>
        public string Validate(T target)
        {
            return RulesValidator.Validate(ValidationRules.GetRules(), target);
        }
                        
        /// <summary>
        /// Initializes this service instance.
        /// </summary>
        /// <param name="source">The <see cref="IServiceContainer"/> that created this service instance.</param>
        public virtual void Initialize(IServiceContainer source)
        {
            ValidationRules = source.GetService<IValidationRules<T>>();
            RulesValidator = source.GetService<IRulesValidator>();
        }        
    }
}
    